package com.qdlc.p2p.biz.web.action;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

import javax.annotation.Resource;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Result;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qd.p2p.sina.service.SinaPayService;
import com.qdlc.p2p.biz.service.AccountBankService;
import com.qdlc.p2p.biz.service.AccountLogService;
import com.qdlc.p2p.biz.service.AccountService;
import com.qdlc.p2p.biz.service.AuthenticationLogService;
import com.qdlc.p2p.biz.service.BorrowRepaymentService;
import com.qdlc.p2p.biz.service.BorrowService;
import com.qdlc.p2p.biz.service.BorrowTenderService;
import com.qdlc.p2p.biz.service.DictService;
import com.qdlc.p2p.biz.service.TppService;
import com.qdlc.p2p.biz.service.TppTradeService;
import com.qdlc.p2p.biz.service.UserIdentifyService;
import com.qdlc.p2p.biz.service.UserService;
import com.qdlc.p2p.biz.task.ConcurrentUtil;
import com.qdlc.p2p.biz.tpp.TppBaseInterface;
import com.qdlc.p2p.biz.tpp.TppServiceFactory;
import com.qdlc.p2p.biz.tpp.model.SinaAuditMemberInfos;
import com.qdlc.p2p.biz.tpp.model.SinaQueryBankCard;
import com.qdlc.p2p.common.constant.BorrowStatus;
import com.qdlc.p2p.common.constant.BorrowTenderStatus;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.constant.LogTplNid;
import com.qdlc.p2p.common.constant.SinaConstant;
import com.qdlc.p2p.common.exception.MemberAgentException;
import com.qdlc.p2p.common.exception.TppChinapnrException;
import com.qdlc.p2p.common.exception.UserException;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.MessageUtil;
import com.qdlc.p2p.common.util.NumberUtil;
import com.qdlc.p2p.common.util.SinaSignUtil;
import com.qdlc.p2p.common.util.SinaTools;
import com.qdlc.p2p.common.util.StringUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.SystemConfigHelper.Nid;
import com.qdlc.p2p.dal.common.model.jpa.QueryParam;
import com.qdlc.p2p.dal.dao.AccountDao;
import com.qdlc.p2p.dal.dao.MemberInfosDao;
import com.qdlc.p2p.dal.dao.TppMemberAgentDao;
import com.qdlc.p2p.dal.dao.TppTradeLogDao;
import com.qdlc.p2p.dal.dto.Account;
import com.qdlc.p2p.dal.dto.AccountBank;
import com.qdlc.p2p.dal.dto.AccountLog;
import com.qdlc.p2p.dal.dto.Borrow;
import com.qdlc.p2p.dal.dto.BorrowRepayment;
import com.qdlc.p2p.dal.dto.BorrowTender;
import com.qdlc.p2p.dal.dto.Dict;
import com.qdlc.p2p.dal.dto.MemberAgent;
import com.qdlc.p2p.dal.dto.MemberInfos;
import com.qdlc.p2p.dal.dto.Tpp;
import com.qdlc.p2p.dal.dto.TppTradeLog;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserIdentify;
import com.qdlc.p2p.dal.model.AccountCashModel;
import com.qdlc.p2p.dal.model.BorrowModel;
import com.qdlc.p2p.dal.model.TppModel;
import com.qdlc.p2p.dal.model.UserModel;
import com.qdlc.p2p.dal.util.UserUtils;

/**
 * 新浪第三方回调
 *
 * @author ylx
 * @version 2.0
 * @date 2015年8月10日 上午11:50:07
 */
@SuppressWarnings("rawtypes")
public class TppSinaAction extends BaseAction {

    private Logger logger = Logger.getLogger(TppSinaAction.class);

    @Resource
    private UserService userService;
    @Resource
    private BorrowService borrowService;
    @Resource
    private BorrowRepaymentService borrowRepaymentService;

    @Resource
    private UserIdentifyService userIdentifyService;
    @Resource
    private TppTradeService tppTradeService;
    @Resource
    private DictService dictService;
    @Resource
    private AccountBankService accountBankService;
    @Resource
    private TppService tppService;
    @Resource
    private BorrowTenderService borrowTenderService;

    @Resource
    private TppMemberAgentDao tppMemberAgentDao;

    @Resource
    private MemberInfosDao memberInfosDao;

    private Map<String, Object> data;

    @Resource
    private TppTradeLogDao tppTradeLogDao;

    @Resource
    private SinaPayService sinaPayService;

    @Resource
    private AccountService accountService;

    @Resource
    private AccountLogService accountLogService;

    @Resource
    private AccountDao accountDao;

    @Resource
    private AuthenticationLogService authenticationLogService;
    
    private final static ReentrantLock lock = new ReentrantLock();

    private static ConcurrentHashMap<String, Boolean> safeMap = new ConcurrentHashMap<String, Boolean>();


    /**
     * 新浪实名
     *
     * @throws Exception --------------------------------------------------------------------
     * @throws Exception
     * @Action(value = "/tpp/tppSinaAction/realName", interceptorRefs = {
     * @InterceptorRef("session"), @InterceptorRef("globalStack") })
     * public void realName() throws Exception {
     * data = new HashMap<String, Object>();
     * <p/>
     * User user = userService.find(getSessionUserId());
     * UserIdentify userIdentify = userIdentifyService.findByUserId(getSessionUserId());
     * if(userIdentify.getRealNameStatus() == 1) {
     * throw new UserException("您已实名，请勿重复实名", 1);
     * }
     * String realName = paramString("realName");
     * String cardId = paramString("cardId");
     * UserModel userModel = UserModel.instance(user);
     * userModel.setRealName(realName);
     * userModel.setCardId(cardId);
     * <p/>
     * TppModel model = new TppModel();
     * model.setUser(userModel);
     * TppBaseInterface tppService = (TppBaseInterface) model.tppServiceFactory();
     * try {
     * tppService.tppRealName(model);
     * user.setTppStatus((byte) 1);
     * user.setRealName(realName);
     * user.setCardId(cardId);
     * userService.update(user);
     * userIdentifyService.modifyRealnameStatus(getSessionUserId(), 1, 0);
     * data.put("result", true);
     * } catch (Exception e) {
     * // throw new UserException(e.getMessage());
     * data.put("msg", e.getMessage());
     * data.put("result", false);
     * }
     * printWebJson(getStringOfJpaObj(data));
     * }
     * --------------------------------------------------
     * <p/>
     * <p/>
     * /**
     * 新浪绑定认证信息
     */
    @Action(value = "/tpp/tppSinaAction/bindingVerify", interceptorRefs = {@InterceptorRef("session"),
            @InterceptorRef("globalStack")})
    public void bindingVerify() throws Exception {
        data = new HashMap<String, Object>();

        User user = userService.find(getSessionUserId());
        UserIdentify userIdentify = userIdentifyService.findByUserId(getSessionUserId());
        if (userIdentify.getTppMobilePhoneStatus() == 1) {
            throw new UserException("您已绑定手机号，请勿重复绑定", 1);
        }
        String tppMobilePhone = paramString("tppMobilePhone");
        String tppVerifyType = paramString("tppVerifyType");
        UserModel userModel = UserModel.instance(user);
        //TODO userModel.setTppMobilePhone(tppMobilePhone);
        userIdentify.setTppVerifyType(tppVerifyType);

        TppModel model = new TppModel();
        model.setUser(userModel);
        TppBaseInterface tppService = TppServiceFactory.newIntance();
        try {
            tppService.bindingVerify(model, userIdentify, null);
            //TODO user.setTppMobilePhone(tppMobilePhone);
            userService.update(user);
            userIdentifyService.modifyTppMobilePhoneStatus(getSessionUserId(), 1, 0);
            data.put("result", true);
        } catch (Exception e) {
            // throw new UserException(e.getMessage());
            data.put("msg", e.getMessage());
            data.put("result", false);
        }
        printWebJson(getStringOfJpaObj(data));
    }

    /**
     * 判断法人手机号码是否已被使用
     *
     * @return
     * @throws Exception
     */
    @Action(value = "/tpp/tppSinaAction/checkLegalPersonPhone", interceptorRefs = {@InterceptorRef("ajaxSafe"),
            @InterceptorRef("globalStack")})
    public String checkLegalPersonPhone() throws Exception {

        String legal_person_phone = request.getParameter("legalPersonPhone");// 法人手机号码
        // 存在校验（法人身份证号码、法人手机号）（新浪经办人信息不能重复存在）
        boolean exsit = memberInfosDao.exsitLegalPersonPhone(legal_person_phone);
        printWebJson(getStringOfJpaObj(!exsit));
        return null;
    }

    /**
     * 判断法人证件号码是否已被使用
     *
     * @return
     * @throws Exception
     */
    @Action(value = "/tpp/tppSinaAction/checkCertNo", interceptorRefs = {@InterceptorRef("ajaxSafe"),
            @InterceptorRef("globalStack")})
    public String checkCertNo() throws Exception {

        String cert_no = request.getParameter("certNo");// 法人证件号码
        // 存在校验（法人身份证号码、法人手机号）（新浪经办人信息不能重复存在）
        Map<String, String> params = new HashMap<String, String>();
        params.put("cert_no", cert_no);

        boolean exsit = memberInfosDao.exsitCertNo(cert_no);
        printWebJson(getStringOfJpaObj(!exsit));
        return null;
    }

    /**
     * 充值同步回调
     *
     * @param
     * @return
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    @Action(value = "/tpp/tppSinaAction/tppRechargeReturn", results = {
            @Result(name = "result", type = "ftl", location = "/retresult.html")})
    public String tppRechargeReturn() throws IOException {
        String resultFlag = System.currentTimeMillis() + "" + (Math.random() * 10000);
        request.setAttribute("resultFlag", resultFlag);
        request.setAttribute("left_url", "/member/main.html"); // 成功返回地址
        request.setAttribute("right_url", "/member/recharge/newRecharge.html"); // 成功返回地址
        request.setAttribute("back_url", "/member/main.html"); // 成功返回地址
        request.setAttribute("left_msg", MessageUtil.getMessage("MS104002001"));
        request.setAttribute("right_msg", MessageUtil.getMessage("MF104002001"));
        request.setAttribute("r_msg", "新浪已受理，请等待！");
        Global.TASK_RESULT_MAP.put(resultFlag, "success");
        return "result";
    }

    /**
     * 代收 同步回调
     *
     * @param
     */
    @Action(value = "/tpp/tppSinaAction/tppCollectTradeReturn")
    public void tppCollectTradeReturn() {
        logger.info("----代收 同步回调 -----");
    }


    /**
     * 代收成功投标业务处理
     *
     * @param tppTradeLog
     * @param resultFlag
     * @param
     * @throws Exception
     */
    public void doTender(TppTradeLog tppTradeLog, String resultFlag) throws Exception {
        BorrowModel bm = new BorrowModel();
        String type = tppTradeLog.getServiceType();
        long borrowId = tppTradeLog.getBorrowId();
        String tppUserCustId = tppTradeLog.getTppUserCustId();
        bm.setId(borrowId);
        bm.setBidNo(tppTradeLog.getOrderNo());
        bm.setTenderBilNo(tppTradeLog.getOrderNo());
        bm.setTenderBilDate(DateUtil.dateStr3(tppTradeLog.getTradeTime()));
        // borrowTender的account金额包含现金、红包、体验券
        bm.setMoney(tppTradeLog.getAmount());
        bm.setTppUserCustId(tppUserCustId);

        // // 更新还款代收调度状态
        // Tpp tpp = tppService.getTppByOrdId(tppTradeLog.getOrderNo());
        // if (tpp != null) {
        // if (tpp.getStatus() != 1) {
        // tpp.setStatus(TppModel.STATUS_SUCEESS);
        // tpp.setRespDesc("代收处理成功");
        // tppService.update(tpp);
        // } else if (tpp.getStatus() == 1) {
        // logger.info("异步回调成功success");
        // response.getWriter().print("success");
        // }
        // }

        if (SinaConstant.TRADE_SERVICE_AUTO_TENDER.equals(type)) {
            ConcurrentUtil.doAutoTender(bm, resultFlag);
        } else if (SinaConstant.TRADE_SERVICE_TENDER.equals(type)) {
            JSONObject merPivJson = JSON.parseObject(tppTradeLog.getMemo());
            long rateInterestId = NumberUtil.getLong(merPivJson.getString("rateId"));
            String redEnvelopeStr = merPivJson.getString("redStr");
            double redEnvelopeMoney = merPivJson.getDoubleValue("redMoney");
            String experStr = merPivJson.getString("experStr");
            double experienceMoney = merPivJson.getDoubleValue("experMoney");
            long userId = NumberUtil.getLong(merPivJson.getString("userId"));
            bm.setUserId(userId);
            bm.setRateInterestId(rateInterestId);
            bm.setRedEnvelopeStr(redEnvelopeStr);
            bm.setTotalRedEnvelopeMoney(redEnvelopeMoney);
            bm.setExperiences((long[]) ConvertUtils.convert(experStr.split(","), long.class));
            bm.setTotalExperienceMoney(experienceMoney);
            ConcurrentUtil.doAddTender(bm, resultFlag);
            // 如果 虚拟金（体验金+红包等）代收成功，执行放款
        } else if (SinaConstant.TRADE_SERVICE_VIRTUAL.equals(type)) {
            ConcurrentUtil.autoVerifyFullSuccess(bm);
        } else if (SinaConstant.TRADE_SERVICE_RED_ENVELOPE_EXCHAGE.equals(type)) {
            // 现金红包兑换待收成功，执行付款
            tppTradeLog.setTradeType(SinaConstant.TRADE_CODE_2001);
            ConcurrentUtil.tppPayTrade(tppTradeLog);
        }

    }

    /**
     * 代收异步回调成功还款处理
     *
     * @param tppTradeLog
     * @param resultFlag
     * @param
     * @throws Exception
     */
    public void doRepay(TppTradeLog tppTradeLog, String resultFlag) throws Exception {
        long borrowRepaymentId = tppTradeLog.getBorrowRepaymentId();
        BorrowRepayment borrowRepayment = borrowRepaymentService.find(borrowRepaymentId);
        if (borrowRepayment != null) {
            List<TppTradeLog> list = tppTradeService.find(borrowRepaymentId, tppTradeLog.getServiceType(),
                    tppTradeLog.getTradeType());
            for (TppTradeLog log : list) {
                if (!SinaConstant.TRADE_STATUS_PAY_FINISHED.equals(log.getTradeStatus())) {
                    logger.info("还款前的代收未处理完毕...");
                    return;
                }
            }
            borrowService.notifySuccessRepay(borrowRepayment);
        }
    }

    /**
     * 代收代付 交易异步回调失败 处理
     *
     * @param tppTradeLog
     * @param
     */
    public void doTradeNotifyFail(TppTradeLog tppTradeLog) {
        // 如果是投标/自动投标失败，则执行投标失败方法，其他执行调度任务失败处理
        if (SinaConstant.TRADE_SERVICE_AUTO_TENDER.equals(tppTradeLog.getServiceType())
                || SinaConstant.TRADE_SERVICE_TENDER.equals(tppTradeLog.getServiceType())) {
            doTenderFail(tppTradeLog);
        } else {
            doTppFail(tppTradeLog);
        }
    }

    /**
     * 投标失败处理
     *
     * @param tppTradeLog
     * @param
     */
    public void doTenderFail(TppTradeLog tppTradeLog) {

        String tenderBilNo = tppTradeLog.getOrderNo();
        BorrowTender borrowTender = borrowTenderService.find(tenderBilNo);
        if (borrowTender != null) {
            Borrow borrow = borrowService.find(borrowTender.getBorrow().getId());
            if (BorrowStatus.STATUS_TRIAL_PASSED == borrow.getStatus()) {
                if (borrowTender.getStatus() != 2) {
                    logger.info("投资记录回滚业务处理 START=====");
                    borrowTender.setStatus(BorrowTenderStatus.FAIL);
                    borrowTenderService.update(borrowTender);
                    double accountYes = BigDecimalUtil.sub(borrow.getAccountYes(), borrowTender.getAccount());
                    borrow.setAccountYes(accountYes);
                    borrowService.update(borrow);
                    // 解冻投标资金
					accountService.deductUseMoneyAndTotal(borrowTender.getUser().getUserId(), borrow.getUser().getUserId(),
							borrowTender.getRealAmount());
                } else {
                    logger.info("投资记录回滚业务已被处理。");
                }
            } else {
                tppTradeLog.setMemo("代收交易结果失败，投资记录回滚失败！");
            }
        }
    }

    /**
     * 代收代付，异步回调结果中交易状态为失败时,更新调度任务状态为失败
     *
     * @param tppTradeLog
     * @param
     */
    public void doTppFail(TppTradeLog tppTradeLog) {
        Tpp tpp = tppService.getTppByOrdId(tppTradeLog.getOrderNo());
        if (tpp != null) {
            tpp.setStatus(TppModel.STATUS_FAIL);
            tpp.setRespDesc("代付处理失败");
            tppService.update(tpp);
        }
    }

    /**
     * 代付 同步回调
     *
     * @param
     */
    @Action(value = "/tpp/tppSinaAction/tppPayTradeReturn")
    public void tppPayTradeReturn() {
        logger.info("----代付 同步回调 -----");
    }

    @Action(value = "/tpp/tppSinaAction/tppPayTradeNotify")
    public void tppPayTradeNotify() {
        //logger.info("----代付 异步回调 -----");
        doPayTrade();
    }

    public void doPayTrade() {
        response.setContentType("text/html;charset=UTF-8");
        String sign = request.getParameter("sign");
        String sign_type = request.getParameter("sign_type");
        Map<String, String> map = SinaTools.getParameterMap(request, true);
        String like_result = SinaTools.createLinkString(map, false);
        String _input_charset = request.getParameter("_input_charset");
        String signKey = "";
        if ("MD5".equalsIgnoreCase(sign_type.toString())) {
            signKey = SystemConfigHelper.getValue(Nid.GOODS_KEY);
        } else {
            signKey = SystemConfigHelper.getValue(Nid.CHECK_SIGN_KEY);
        }
        try {
            boolean result = SinaSignUtil.Check_sign(like_result.toString(), sign, sign_type, signKey, _input_charset);
            String deposit_status = map.get("trade_status");
            logger.info("----代付 异步回调 -----" + deposit_status);
            String out_trade_no = map.get("outer_trade_no");
            String deposit_amount = map.get("trade_amount");

            if (result) {
                // 新浪调用Log都会生成
                TppTradeLog tppTradeLog = tppTradeService.find(out_trade_no);
                // Tpp在调用新浪接口之后才生成，所以 如果还没生成，我们直接返回err等待生成
                // 自动投标和投标不生成tpp
                Tpp tpp = tppService.getTppByOrdId(out_trade_no);
                if ((tppTradeLog == null) && (tpp != null)) {
                    tppTradeLog = tppTradeService.find(tpp.getSubOrdId());
                }

                // 异步回调 订单状态为成功情况
                if (tppTradeLog == null) {
                    logger.info("代付订单号：" + out_trade_no + "不存在！");
                    response.getWriter().print("no out_trade_no!");
                    return;
                }
                // 判断是否已经成功过
                String sinaStatus = tppTradeLog.getSinaStatus();

                // 异步回调 订单状态为已结束情况
                if ((sinaStatus == null) || !sinaStatus.contains(deposit_status)) {
                    if (SinaConstant.TRADE_STATUS_FINISHED.equals(deposit_status)) {
                        logger.info(deposit_status + " 代付订单号回调处理 [" + out_trade_no + "]" + "交易号 [" + tppTradeLog.getTradeType() + "]");
                        // 交易完成需更新状态，以免挂起
                        if (!"tender".equals(tppTradeLog.getServiceType())
                                && !"autotender".equals(tppTradeLog.getServiceType())) {
                            if (tpp == null) {
                                logger.info("等待生成待收信息 tpp! " + deposit_status);
                                response.getWriter().print("tpp error!");
                                // 更新状态，这样可以让调度不成挂起（在网络不太流畅或并发时可能会造成这情况）
                                return;
                            } else if (tpp.getStatus() != TppModel.STATUS_SUCEESS) {
                                logger.info("订单状态更新为成功!");
                                tpp.setStatus(TppModel.STATUS_SUCEESS);
                                tpp.setRespDesc("代付成功");
                                tppService.update(tpp);
                            }
                        }
                    } else if (SinaConstant.TRADE_STATUS_PAY_FINISHED.equals(deposit_status)) {
                        logger.info(deposit_status + " 代付订单号回调处理 [" + out_trade_no + "]" + "交易号 [" + tppTradeLog.getTradeType() + "]");
                        tppTradeLog.setAmount(StringUtil.toDouble(deposit_amount));
                        tppTradeLog.setTradeStatus(deposit_status);
                        tppTradeLog.setTradeTime(DateUtil.getNow());
                        tppTradeService.update(tppTradeLog);
                        // 异步回调 订单状态为失败情况
                    } else if (SinaConstant.TRADE_STATUS_FAILED.equals(deposit_status)) {
                        logger.info(deposit_status + " 代付订单号回调处理 [" + out_trade_no + "]" + "交易号 [" + tppTradeLog.getTradeType() + "]");
                        tppTradeLog.setTradeStatus(deposit_status);
                        tppTradeLog.setTradeTime(DateUtil.getNow());
                        doTradeNotifyFail(tppTradeLog);
                        tppTradeService.update(tppTradeLog);
                    }
                    // 状态是否已经执行过
                    if (sinaStatus == null) {
                        tppTradeLog.setSinaStatus(deposit_status);
                    } else {
                        tppTradeLog.setSinaStatus(sinaStatus + " " + deposit_status);
                    }
                    tppTradeService.update(tppTradeLog);
                } else {
                    logger.info(out_trade_no + " " + deposit_status + " 状态已经被执行过!");
                }
                logger.info(out_trade_no + " 代付异步回调成功 " + deposit_status);
                response.getWriter().print("success");
            } else {
                logger.info(out_trade_no + " 代付异步回调失败sign error " + deposit_status);
                response.getWriter().print("sign error!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    /**
     * 企业开户异步回调
     *
     * @throws Exception
     */
    @Action(value = "/tpp/tppSinaAction/tppAuditMemberInfosNotice")
    public void tppAuditMemberInfosNotice() throws Exception {
        logger.info("企业开户异步回调 start===");
        boolean result = doAuditMemberInfosNotice();
        try {
            if (result) {
                response.setContentType("text/html;charset=UTF-8");
                logger.info("异步回调成功success");
                response.getWriter().print("success");
            } else {
                response.setContentType("text/html;charset=UTF-8");
                logger.info("异步回调失败sign error!");
                response.getWriter().print("sign error!");
            }
            logger.info("企业开户异步回调 end===");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 企业开户业务处理
     *
     * @return
     */
    public boolean doAuditMemberInfosNotice() {
        String sign = request.getParameter("sign");
        String sign_type = request.getParameter("sign_type");
        Map<String, String> map = SinaTools.getParameterMap(request, true);
        String like_result = SinaTools.createLinkString(map, false);
        String _input_charset = request.getParameter("_input_charset");
        boolean result = false;
        try {
            result = SinaSignUtil.Check_sign(like_result.toString(), sign, sign_type, SystemConfigHelper.getValue(Nid.GOODS_KEY),
                    _input_charset);
            String audit_order_no = map.get("audit_order_no");// 请求审核订单号
            String inner_order_no = map.get("inner_order_no");// 内部交易凭证号
            String audit_status = map.get("audit_status");// 审核结果
            String audit_message = map.get("audit_message");// 审核结果建议

            QueryParam param = QueryParam.getInstance();
            param.addParam("auditOrderNo", audit_order_no);
            MemberInfos mi = memberInfosDao.findByCriteriaForUnique(param);
            User user = UserUtils.getUserById(mi.getUserId());
            if (null == mi) {
                throw new TppChinapnrException(MessageUtil.getMessage("MF104001003"));
            }
            if (mi.getStatus() == 1) {
                return true;
            }

            SinaAuditMemberInfos memberInfos = new SinaAuditMemberInfos();
            memberInfos.setAudit_order_no(audit_order_no);
            memberInfos.setInnerOrderNo(inner_order_no);
            memberInfos.setAuditMessage(audit_message);

            logger.info("======企业开户回调订单号：" + audit_order_no);
            if (audit_status.equals(SinaConstant.AUDIT_MEMBER_INFOS_SUCCESS)) {

                logger.info("=======企业开户回调审核结果：通过");
                // 企业开户成功
                memberInfos.setAuditStatus((byte) 1);

                boolean errorFlag = false;// 是否存在错误flag
                // 更新用户银行账户信息表
                // 请求查询银行卡接口，获取第三方系统卡ID
                List<AccountBank> bankList = accountBankService.listAll(user.getUserId());
                if (bankList.size() <= 0) {// 排除已处理
                    TppModel tppModel = new TppModel();
                    tppModel.setUser(user);
                    TppBaseInterface tppService = TppServiceFactory.newIntance();
                    SinaQueryBankCard queryBankCard = (SinaQueryBankCard) tppService.tppQueryBankCard(tppModel);
                    if (queryBankCard == null) {
                        // 银行卡绑卡失败
                        errorFlag = true;
                        throw new TppChinapnrException(MessageUtil.getMessage("I20006"));
                    }
                    String Card_list[] = queryBankCard.getCard_list().split("\\^");
                    // 卡信息ID
                    String card_id = "";
                    if (Card_list.length > 0) {
                        card_id = Card_list[0];
                    }
                    Dict dict = dictService.find("account_bank", mi.getBankCode());
                    AccountBank bank = (AccountBank) paramModel(AccountBank.class);
                    bank.setUserId(user.getUserId());
                    bank.setBankNo(mi.getBankAccountNo());
                    bank.setProvince(mi.getProvince());
                    bank.setCity(mi.getCity());
                    bank.setArea(mi.getBankBranch());
                    bank.setBank(dict.getId());
                    bank.setPicPath("/data/bank/mini/" + dict.getValue() + ".png");
                    bank.setTppCardId(card_id);
                    int countTotal = accountBankService.count(user.getUserId());
                    int defaultTotal = SystemConfigHelper.getIntegerValue(Nid.BANK_NUM);
                    AccountCashModel m = new AccountCashModel();
                    m.setComfirmAccount(mi.getBankAccountNo());
                    m.validAddBank(countTotal, defaultTotal, bank);

                    AccountBank ab = accountBankService.findByBankNo(bank.getBankNo());
                    if (ab == null) {
                        accountBankService.save(bank);
                    } else {
                        ab.setAddIp(Global.getIP());
                        ab.setAddTime(DateUtil.getNow());
                        ab.setArea(bank.getArea());
                        ab.setBank(bank.getBank());
                        ab.setBranch(bank.getBranch());
                        ab.setCity(bank.getCity());
                        ab.setPicPath(bank.getPicPath());
                        ab.setProvince(bank.getProvince());
                        ab.setStatus(1);
                        accountBankService.update(ab);
                    }
                }

                logger.info("=======企业开户回调审核通过，业务处理成功；开始经办人信息录入");
                // 经办人信息录入
                MemberAgent memberAgent = tppMemberAgentDao.findMemberAgentByUserId(user.getUserId());
                param.addParam("auditOrderNo", audit_order_no);
                MemberInfos memberInfo = memberInfosDao.findByCriteriaForUnique(param);
                if (memberAgent.getStatus() != 1) { // 排除已处理

                    String agent_name = memberInfo.getLegalPerson();// 经办人姓名
                    String license_no = memberInfo.getCertNo();// 证件号码
                    String agent_mobile = memberInfo.getLegalPersonPhone();// 经办人手机号

//                    user.getMemberAgent().setAgent_name(agent_name);
//                    user.getMemberAgent().setAgent_mobile(agent_mobile);
//                    user.getMemberAgent().setLicense_no(license_no);

                    memberAgent.setAgent_name(agent_name);
                    memberAgent.setLicense_no(license_no);
                    memberAgent.setAgent_mobile(agent_mobile);
                    memberAgent.setAddTime(DateUtil.getNow());
                    memberAgent.setAddIp(Global.getIP());

                    TppModel agentModel = new TppModel();
                    agentModel.setUser(user);
                    TppBaseInterface tppAgentService = TppServiceFactory.newIntance();

                    try {
                        tppAgentService.tppMemberAgent(agentModel, memberInfo);
                        memberAgent.setStatus((byte) 1);
                        logger.info("======经办人信息录入成功");
                    } catch (Exception e) {
                        errorFlag = true;
                        logger.error("=====经办人信息录入失败");
                    }
                }

                logger.info("=======企业开户回调审核通过，业务处理成功；经办人信息录入处理完成；开始绑定认证信息");
                // 绑定认证信息
                String tppUserMobilePhone = UserUtils.getUserTppMobilePhone(user.getUserId());
                if (StringUtils.isNotEmpty(tppUserMobilePhone)) {
                    UserIdentify userIdentify = userIdentifyService.findByUserId(user.getUserId());
                    String tppMobilePhone = memberInfo.getLegalPersonPhone();
                    String tppVerifyType = "MOBILE";// 默认为手机
                    UserModel userModel = UserModel.instance(user);
                    //TODO userModel.setTppMobilePhone(tppMobilePhone);
                    userIdentify.setTppVerifyType(tppVerifyType);
                    userIdentify.setTppMobilePhoneStatus(1);

                    TppModel model = new TppModel();
                    model.setUser(userModel);
                    TppBaseInterface ts = TppServiceFactory.newIntance();
                    try {
                        ts.bindingVerify(model, userIdentify, memberInfo);
                        //TODO user.setTppMobilePhone(tppMobilePhone);
                        userService.update(user);
                        logger.info("========绑定认证信息成功");
                    } catch (Exception e) {
                        errorFlag = true;
                        logger.error("=======绑定认证信息失败");
                    }
                }
                // 是否有未成功的接口，有的场合不更新状态
                if (!errorFlag) {
                    // 更新本地业务状态
                    ConcurrentUtil.tppAuditMemberInfosSuccess(memberInfos, null);
                }

            } else if (audit_status.equals(SinaConstant.AUDIT_MEMBER_INFOS_FAILED)) {

                // 企业开户不通过
                memberInfos.setAuditStatus((byte) 2);
                ConcurrentUtil.tppAuditMemberInfosFail(memberInfos, null);
                logger.error("=======企业开户回调审核结果：不通过；审核结果建议：" + audit_message);
            }
        } catch (Exception e) {
            logger.error("企业开户回调校验不通过...");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 退款同步回调
     *
     * @throws Exception
     */
    @Action(value = "/tpp/tppSinaAction/tppRefundReturn")
    public void tppRefundReturn() throws Exception {
        logger.info("退款同步回调成功... ");
    }

    /**
     * 退款异步回调
     *
     * @throws Exception
     */
    @Action(value = "/tpp/tppSinaAction/tppRefundNotify")
    public void tppRefundNotice() throws Exception {
        logger.info("退款异步回调开始... ");
        doRefund();
    }

    public void doRefund() {
        lock.lock();
        response.setContentType("text/html;charset=UTF-8");
        String sign = request.getParameter("sign");
        String sign_type = request.getParameter("sign_type");
        Map<String, String> map = SinaTools.getParameterMap(request, true);
        String like_result = SinaTools.createLinkString(map, false);
        String _input_charset = request.getParameter("_input_charset");
        try {
            boolean result = SinaSignUtil.Check_sign(like_result.toString(), sign, sign_type,
            		SystemConfigHelper.getValue(Nid.GOODS_KEY), _input_charset);
            String refund_status = map.get("refund_status");
            String out_trade_no = map.get("outer_trade_no");
            double refund_amount = StringUtil.toDouble(map.get("refund_amount"));

            if (safeMap.size() > 100 && null == safeMap.get(out_trade_no)) {
                safeMap.clear();
            }
            if (null != safeMap.get(out_trade_no)) {
                logger.info("=======退款异步回调订单号：" + out_trade_no + "，已处理过，直接返回！");
                response.getWriter().print("success");
                return;
            }
            safeMap.put(out_trade_no, true);
            logger.info("=======退款异步回调订单号：" + out_trade_no);
            Tpp tpp = tppService.getTppByOrdId(out_trade_no);
            if (result && refund_status.equals(SinaConstant.REFUND_STATUS_SUCCESS) && (tpp != null)) {
                String tppUserCustId = tpp.getTppUserCustId();
                User user = UserUtils.getUserByTppCustId(tppUserCustId);
                //红包退款,判断是否更新用户账户金额
                if (null != user && null == tpp.getTender() && TppModel.REFUNDBYSUBORDIDY.equals(tpp.getServiceType())) {
                    logger.info("退款，更新用户[" + user.getUserId() + "]账户金额：" + refund_amount);
                    Account account = accountDao.findByUserId(user.getUserId());
                    //user用户
                    AccountLog log = new AccountLog(user, LogTplNid.SINA_REFUND, new User(1));
                    log.setMoney(refund_amount);
                    log.setTotal(account.getTotal());
                    log.setUseMoney(account.getUseMoney());
                    log.setNoUseMoney(account.getNoUseMoney());
                    log.setCollection(account.getCollection());
                    log.setPaymentsType((byte) 2);
                    log.setName("退款");
                    log.setRemark("红包兑换失败，扣除本地金额" + refund_amount + "元");
                    accountLogService.add(log);
                    //更新用户账户总额和可用金额
                    account.setUseMoney(account.getUseMoney() - refund_amount);
                    account.setTotal(account.getTotal() - refund_amount);
                    accountService.updateAccount(account);
                }
                logger.info("异步回调成功，状态：" + refund_status);
                response.getWriter().print("success");
            } else {
                logger.info("异步回调失败sign error!");
                response.getWriter().print("sign error!");
            }
        } catch (Exception e) {
            logger.error("退款回调校验不通过...");
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 经办人信息
     */
    @Action(value = "/tpp/tppSinaAction/smt", interceptorRefs = {@InterceptorRef("session"),
            @InterceptorRef("globalStack")})
    public void smtfundagentbuy() throws Exception {
        data = new HashMap<String, Object>();

        User user = userService.find(getSessionUserId());

        MemberAgent memberAgent = tppMemberAgentDao.findMemberAgentByUserId(getSessionUserId());
        if (memberAgent.getStatus() == 1) {
            throw new MemberAgentException("你已通过经办人认证，请勿重复操作", 1);
        }
        String agent_name = paramString("agent_name");// 经办人姓名
        String license_no = paramString("license_no");// 证件号码
        String agent_mobile = paramString("agent_mobile");// 经办人手机号

//        user.getMemberAgent().setAgent_name(agent_name);
//        user.getMemberAgent().setAgent_mobile(agent_mobile);
//        user.getMemberAgent().setLicense_no(license_no);

        memberAgent.setAgent_name(agent_name);
        memberAgent.setLicense_no(license_no);
        memberAgent.setAgent_mobile(agent_mobile);

        memberAgent.setAddIp(Global.getIP());

        TppModel model = new TppModel();
        model.setUser(user);
        TppBaseInterface tppService = TppServiceFactory.newIntance();

        try {
            tppService.tppMemberAgent(model, null);
            memberAgent.setStatus((byte) 1);
            tppMemberAgentDao.update(memberAgent);
            data.put("result", true);
        } catch (Exception e) {
            data.put("msg", e.getMessage());
            data.put("result", false);
        }
        printWebJson(getStringOfJpaObj(data));

    }

}
